﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Cors.Internal;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using QBZ.Evaluation.Domains;
using QBZ.Evaluation.Domains.OAuth;
using QBZ.Evaluation.Domains.Permissions;
using QBZ.Evaluation.Repositories;
using QBZ.Evaluation.Repositories.DataAccess;
using System;
using System.Text;

namespace QBZ.Evaluation.Apis
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddDbContext<dbEvaluationContext>(options =>
                options.UseSqlServer("Server=123.206.90.82,1433;Database=dbEvaluation;user id=sa;pwd=Qb123456."));
            services.AddScoped<UserDomain>();
            services.AddScoped<UserRepository>();
            services.AddScoped<SkillDomain>();
            services.AddScoped<SkillRepository>();
            services.AddScoped<RoleDomain>();
            services.AddScoped<RoleRepository>();
            services.AddMemoryCache();

            services.Configure<JwtSettings>(Configuration.GetSection("JwtSettings"));

            // assign JwtSettings model
            var jwtSettings = new JwtSettings();
            Configuration.Bind("JwtSettings", jwtSettings);
            services.AddAuthentication(options =>
            {
                //Auth middleware config
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(o =>
            {
                // set jwt token parameters
                o.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidIssuer = jwtSettings.Issuer,//Issuer
                    ValidAudience = jwtSettings.Audience,//Audience
                    //Encryption secret key
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey)),
                    ValidateIssuer = true, //whether or not valid Issuer
                    ValidateAudience = true, //whether or not valid Audience
                    ValidateLifetime = true, //whether or not valid out-of-service time
                    ValidateIssuerSigningKey = true, //whether or not valid SecurityKey　　　　　　　　　　　
                    ClockSkew = TimeSpan.Zero//Allowed server time offset
                };
            });
            services.AddCors(o => o.AddPolicy("AllowAll", builder =>
            {
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader()
                       .AllowCredentials()
                       .SetPreflightMaxAge(TimeSpan.FromSeconds(2520))
                       .Build();
            }));
            // Apply as default to all controllers. API etc
            services.Configure<MvcOptions>(options =>
            {
                options.Filters.Add(new CorsAuthorizationFilterFactory("AllowAll"));
            });
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
            app.UseCors(builder =>
            {
                builder.AllowAnyHeader()
                .AllowAnyMethod()
                .WithOrigins("*")
                .AllowCredentials()
                .SetPreflightMaxAge(TimeSpan.FromSeconds(2520))
                .Build();
            });
            app.UseHttpsRedirection();
            var Credentials = Configuration.GetSection("Credentials").Get<CredentialsSetting>();
            LoginProvider.UseQQ(Credentials.QQ.client_id, Credentials.QQ.client_secret);
            LoginProvider.UseWechat(Credentials.Wechat.client_id, Credentials.Wechat.client_secret);
            LoginProvider.UseWeibo(Credentials.Weibo.client_id, Credentials.Weibo.client_secret);
             //app.UseErrorHandling();
           app.UseAuthentication();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "api/{controller=User}/{action=Index}/{id?}");
            });
        }
    }
}
